package com.java.main.lambda;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toMap;

/**
 * @author 顾志杰
 * @date 2020/7/24-14:03
 */
@Slf4j
public class LambdaTest {
    private static final List<TestDto> LIST = Arrays.asList(
            new TestDto("张三", 1, "男"),
            new TestDto("李四", 2, "男"),
            new TestDto("李四", 4, "男"),
            new TestDto("李四", 2, "女"),
            new TestDto("王五", 3, "女"));

    private static final List<TestDto> LIST2 = Arrays.asList(
            new TestDto("张三", 1, "男"),
            new TestDto("李四", 2, "男"),
            new TestDto("李四", 4, "男"));

    public static void main(String[] args) throws IllegalAccessException, ParseException {
//        LocalDate now = LocalDate.now();
//        // 年第一天
//        LocalDate firstDayOfYear = now.withDayOfYear(1);
//        // 季度第一天
//        int quarter = (now.getMonthValue() - 1) / 3 + 1;
//        LocalDate firstDayOfQuarter = now.withMonth((quarter - 1) * 3 + 1).withDayOfMonth(1);
//        // 月第一天
//        LocalDate firstDayOfMonth = now.withDayOfMonth(1);
//        System.out.println(firstDayOfYear.toString());
//        System.out.println(firstDayOfQuarter.toString());
//        System.out.println(firstDayOfMonth.toString());

//        Iterator<TestDto> iterator = LIST.iterator();
//        while (iterator.hasNext()){
//            TestDto next = iterator.next();
//            if(next.getAge() == 4){
//                iterator.remove();
//            }
//        }
//        LIST.forEach(System.out::println);
//                sort(LIST,"age",1).forEach(System.out::println);
//        LocalDate now = LocalDate.now();
//        int monthValue = now.getMonthValue();
//        int startMonth;
//        if (monthValue >= 1 && monthValue <= 3) {
//            startMonth = Month.JANUARY.getValue();
//        } else if (monthValue >= 4 && monthValue <= 6) {
//            startMonth = Month.APRIL.getValue();
//        } else if (monthValue >= 7 && monthValue <= 9) {
//            startMonth = Month.JULY.getValue();
//        } else {
//            startMonth = Month.OCTOBER.getValue();
//        }
//        System.out.println(startMonth);
        //        LIST.stream().filter(a->a.getSex()==null).forEach(b->{
//            b.setSex("未知");
//        });
//        LIST.forEach(System.out::println);


//        List<TestDto> collect = LIST.stream()
//                .filter(item -> LIST2.stream().noneMatch(a -> a.getName().equals(item.getName())))
//                .collect(Collectors.toList());
//        collect.forEach(System.out::println);


//        String[] strings = {"1", "2", "3"};
//        System.out.println(strings[new Random().nextInt(strings.length)]);

//        sort();
//        LIST.sort(Comparator.comparing(TestDto::getAge).reversed().thenComparing(TestDto::getSex).reversed());
//        LIST.forEach(a->{
//            if(a.getAge()==2){
//                return;
//            }
//            System.out.println(a.toString());
//        });

    /*    int[] nums1 = new int[]{1,2,3,0,0,0};
        int[] nums2 = new int[]{2,3,4};
        System.arraycopy(nums2,0,nums1, nums2.length,nums2.length);
        Arrays.sort(nums1);
        System.out.println(Arrays.toString(nums1));*/
//        groupBy();
//a();

//        TestDto testDto = new TestDto("李四", 2, "男");
//        Arrays.stream(testDto.getClass().getDeclaredFields()).forEach(a->{
//            a.setAccessible(true);
//            System.out.println(a.getName());
//            try {
//                System.out.println(a.get(testDto));
//            } catch (IllegalAccessException e) {
//                throw new RuntimeException(e);
//            }
//        });
//        op(testDto,testDto.getClass());
//        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
//        List<Date> dates = Arrays.asList( dateFormat.parse("2022-11-14"), dateFormat.parse("2022-11-14"), dateFormat.parse("2022-11-13"), dateFormat.parse("2022-11-15"));
//        Date date = dates.stream().max((a, b) -> (int)(a.getTime()-b.getTime())).get();
//        System.out.println(dateFormat.format(date));

//        int num = 1;
//        num++;
//        System.out.println(num);
//        LocalDateTime one = LocalDateTime.of(2022, 11, 14, 0, 0);
//        LocalDateTime two = LocalDateTime.of(2021, 11, 14, 0, 0);
//        LocalDateTime three = LocalDateTime.of(2023, 11, 14, 0, 0);
//        LocalDateTime four = LocalDateTime.of(2024, 11, 14, 0, 0);

        LocalDate visitStartTime = LocalDate.of(2025, 7, 1);
        LocalDate visitEndTime = LocalDate.of(2025, 7, 2);

        LocalDate now = LocalDate.now();

        if (now.isAfter(visitEndTime)) {
            System.out.println(2); // 已结束
        } else if (now.isBefore(visitStartTime)) {
            System.out.println(0); // 未开始
        } else {
            System.out.println(1); // 进行中
        }


//        List<LocalDateTime> list = Arrays.asList(one, two, three, four);
//
//        List<LocalDateTime> collect = list.stream().sorted().collect(Collectors.toList());
//        collect.forEach(System.out::println);
    }

    private static void op(Object o,Class<?> T) throws IllegalAccessException {
        for (Field a : T.getDeclaredFields()) {
            a.setAccessible(true);
            System.out.println(a.getName());
            System.out.println(a.get(o));
        }

    }

    /**
     * 多个集合合成一个
     */
    private static void synthesis(){
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        List<Integer> list2 = Arrays.asList(4, 5, 6);
        List<Integer> list3 = Arrays.asList(7, 8, 9);

        List<Integer> mergedList = Stream.of(list1, list2, list3).flatMap(Collection::stream).collect(Collectors.toList());

        System.out.println(mergedList);// [1, 2, 3, 4, 5, 6, 7, 8, 9]

    }

    /**
     * 分组
     */
    private static void groupBy(){
//        Map<String, List<TestDto>> collect = LIST.stream().collect(Collectors.groupingBy(TestDto::getName));
//        Map<String, List<TestDto>> collect = LIST.parallelStream().collect(Collectors.groupingBy(TestDto::getName));
        //分组并且值只保留对象中一个内容
        Map<String, List<Integer>> collect = LIST
                .parallelStream()
                .collect(Collectors.groupingBy(TestDto::getName,
                        Collectors.mapping(TestDto::getAge, Collectors.toList())
                ));
        collect.keySet().forEach(s-> System.out.println(s+" : " + collect.get(s).size()));
    }


    /**
     * 排序
     */
    private static void sort() {
        LIST.forEach(str -> System.out.println("排序前:" + str.toString()));
        //stream写法 根据条件倒叙 reversed()倒叙
        LIST.stream().sorted(Comparator.comparing(TestDto::getAge).reversed());
        System.out.println("------------------------------------------------------");
        LIST.forEach(System.out::println);
        //lambda 排序 根据条件倒叙 不加lambda 就是正序
        LIST.sort((a, b) -> b.getAge().compareTo(a.getAge()));
        System.out.println("------------------------------------------------------");
        LIST.forEach(System.out::println);
        //根据两个参数排序
        LIST.sort(Comparator.comparing(TestDto::getAge).reversed().thenComparing(TestDto::getSex).reversed());
        System.out.println("------------------------------------------------------");
        LIST.forEach(str -> System.out.println("排序后:" + str.toString()));

    }

    /**
     * 排序2
     */
    private static void sort2(boolean ascending) {
        Comparator<TestDto> comparator = (p1, p2) -> {
            try {
                Field field = TestDto.class.getDeclaredField("age");
                field.setAccessible(true);
                Comparable value1 = (Comparable) field.get(p1);
                Comparable value2 = (Comparable) field.get(p2);
                int result = value1.compareTo(value2);
                return ascending ? result : -result; // 根据ascending参数决定正序或倒序
            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        };

        LIST.stream()
                .sorted(comparator)
                .forEach(System.out::println);
    }

    private static  <T>List<T> sort(List<T> datas,String fieldName,Integer sort){
        Comparator<T> comparator = (p1, p2) -> {
            try {
                Field field = datas.get(0).getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                Comparable value1 = (Comparable) field.get(p1);
                Comparable value2 = (Comparable) field.get(p2);
                int result = value1.compareTo(value2);
                return sort == 1 ? result : -result;
            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        };

        return datas.stream()
                .sorted(comparator).collect(Collectors.toList());
    }

    /**
     * 去重
     */
    private static void distinct() {
        LIST.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
        System.out.println("---------------------------------------------------");
        List<TestDto> collect = LIST.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(TestDto::getName))), ArrayList::new));
        collect.forEach(System.out::println);
        System.out.println("---------------------------------------------------");
    }


    /**
     * 选出数组中最多元素
     */
    private static void a(){
        String[] str = new String[]{"aaa","bbb","ccc","aaa","bbb","aaa"};
        String s = Arrays.stream(str).collect(toMap(w -> w, w -> 1, Integer::sum))
                .entrySet()
                .stream()
                .max(Map.Entry.comparingByValue())
                .map(Map.Entry::getKey).orElse("");
        System.out.println(s);
    }
}
